home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 October: Mac OS SDK / Dev.CD Oct 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw GX / Programming Stuff / Sample Code / Printing Samples / Printer Drivers… / HPXL / ChooserSupport.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-15  |  10.4 KB  |  361 lines  |  [TEXT/MPS ]

  1. /*---------------------------------------------------------------------------
  2. FILENAME
  3.     ChooserSupport.c
  4.  
  5. DESCRIPTION
  6.     This file contains the C code for the PACK and LDEF routines used by the
  7.     Chooser when the HPXL driver is selected in the Chooser.
  8.         
  9. COPYRIGHT
  10.     Copyright Apple Computer, Inc. 1993-1996
  11.     All rights reserved. 
  12.     
  13. INTERFACE ROUTINES:
  14.     Device
  15.     LDEF
  16.  
  17.     12/20/93        dmh        Sync'd up for GX 1.0b3.
  18.      8/28/94        dmh        Sync'd up for GX 1.0.1.
  19.      6/14/96        cn        Updated to support Universal Interfaces 2.1.
  20.  
  21. -------------------------------------------------------------------------------- */
  22.  
  23. #include <Types.h>
  24. #include <QuickDraw.h>
  25. #include <Fonts.h>
  26. #include <Lists.h>
  27. #include <Devices.h>
  28. #include <Resources.h>
  29. #include <Script.h>
  30. #include <ToolUtils.h>
  31. #include <LowMem.h>
  32.  
  33. // Include the new QuickDraw GX graphics header files 
  34. #include <GXGraphics.h>
  35.  
  36. // Include the required Printing Manager header files 
  37. #include <GXPrinterDrivers.h>
  38.  
  39. /*********************************************************************************
  40.  *                                         CONSTANTS                                                     *
  41.  *********************************************************************************/
  42.  
  43. // Chooser initialize message selector
  44. #define    initializeMsg            11
  45.  
  46. // Icon Suite support
  47.  
  48. #define    ttNone                    0x0000
  49. #define    ttDisabled                0x0001
  50. #define    ttOffline                0x0002
  51. #define    ttOpen                    0x0003
  52. #define    ttSelected                 0x4000
  53. #define    ttSelectedDisabled    (ttSelected + ttDisabled)
  54. #define    ttSelectedOffline        (ttSelected + ttOffline)
  55. #define    ttSelectedOpen            (ttSelected + ttOpen)
  56.  
  57. #define    ttLabel0                    0x0000
  58. #define    ttLabel1                    0x0100
  59. #define    ttLabel2                    0x0200
  60. #define    ttLabel3                    0x0300
  61. #define    ttLabel4                    0x0400
  62. #define    ttLabel5                    0x0500
  63. #define    ttLabel6                    0x0600
  64. #define    ttLabel7                    0x0700
  65.  
  66.  
  67. /*********************************************************************************
  68.  *                                    INLINE DECLARATIONS                                            *
  69. **********************************************************************************/
  70.  
  71. pascal OSErr PlotIconSuite(const Rect * theRect, short align, short iconTransform, Handle cIcon)
  72.     = {0x303C, 0x0603, 0xABC9};
  73.  
  74. pascal void OldDrawText(const void *textBuf,short firstByte,short byteCount)
  75.     = 0xA885; 
  76.  
  77.  
  78. /***************************************************************************************
  79. *                                         INTERFACE ROUTINES                                                     *
  80. ***************************************************************************************/                        
  81.  
  82.  
  83. /****************************************************************************************
  84.  
  85.                             Device
  86.                             
  87.     function:
  88.                 This routine is the interface routine for the Chooser PACK.  This is the
  89.                 routine the Chooser calls to perform the Chooser functions for the 
  90.                 LaserWriter IISC driver.
  91.                 
  92.     parameters:                
  93.                 message        specifies which Chooser function to perform    
  94.                 caller        equals 1; specifies the caller is the Chooser
  95.                 objName        name of the selected device
  96.                 zoneName        zone name for AppleTalk devices
  97.                 theList        the list of names
  98.                 p2                parameter used depending upon message value
  99.                 
  100.     returns:
  101.                 OSErr
  102.     
  103. ****************************************************************************************/
  104. pascal OSErr Device(short message, short caller, StringPtr objName, 
  105.                     StringPtr zoneName, ListHandle theList, long p2)
  106. {
  107.     
  108.     OSErr            anErr = noErr;
  109.     extern Str31     gDriverName;
  110.     StringPtr        pDriverName = gDriverName;
  111.     extern gxJob    gJob;                        // Declared in our .a file.
  112.     gxJob            *pJob = &gJob;
  113.  
  114.     if (message == initializeMsg)    // InitializeMsg--start up GX
  115.     {
  116.         FCBPBRec    pb;
  117.  
  118.     /*
  119.         Get the name of our driver for GXHandleChooserMessage.
  120.         (The user may have renamed us.)
  121.     */
  122.         pb.ioCompletion     = nil;
  123.         pb.ioNamePtr         = pDriverName;
  124.         pb.ioVRefNum         = 0;
  125.         pb.ioRefNum         = CurResFile();
  126.         pb.ioFCBIndx         = 0;
  127.         anErr = PBGetFCBInfo(&pb, false);
  128.  
  129.     /*
  130.         Clear *pJob, because it hasn't been initialized yet.  That doesn't
  131.         happen until we pass GXHandleChooserMessage an initializeMsg.
  132.     */
  133.         *pJob = nil;
  134.  
  135.     /*
  136.         We need to initialize GX printing so that we can call
  137.         GXHandleChooserMessage.  Since printing requires a graphics
  138.         client, call GXEnterGraphics first.  If there are errors,
  139.         (for example, due to memory limitations), post an alert.
  140.     */
  141.         if (anErr == noErr)
  142.         {
  143.             GXEnterGraphics();
  144.             anErr = GXGetGraphicsError(nil);
  145.             if (anErr == noErr)
  146.             {
  147.                 anErr = GXInitPrinting();
  148.                 if (anErr != noErr)
  149.                     GXExitGraphics();
  150.             }
  151.                 
  152.             if (anErr != noErr)
  153.                 StopAlert(-4095, nil);
  154.         }
  155.     }
  156.  
  157. /*
  158.     If the Chooser hasn't created a job yet, do nothing unless we were
  159.     sent an initializeMsg.  In its default implementation of
  160.     GXHandleChooserMessage, QuickDraw GX will create the job for our
  161.     driver when it receives an initializeMsg.  It will store a reference
  162.     to it in our pJob pointer.
  163.     
  164.     For all other messages, if a job has been created, call
  165.     GXHandleChooserMessage to handle things.
  166. */
  167.     if (anErr == noErr)
  168.     {
  169.         if ((*pJob != nil) || (message == initializeMsg))
  170.         {
  171.             anErr = GXHandleChooserMessage(pJob, pDriverName, message, caller, objName, zoneName, theList, p2);
  172.     
  173.         /*
  174.             If we just got a terminateMsg, and p2 is also terminateMsg, the
  175.             Chooser is closing.  QuickDraw GX just disposed of the gxJob it
  176.             created earlier when GXHandleChooserMessage was passed
  177.             initializeMsg, so we just need to call GXExitPrinting and
  178.             GXExitGraphics to clean up.
  179.             
  180.             Note that we must test the p2 parameter, because the Chooser
  181.             can also send terminateMsg when it wants to empty the device
  182.             list, but not dispose of us.  For example, this will happen
  183.             when the user turns off AppleTalk in the Chooser.
  184.         */
  185.             if ((message == terminateMsg) && (p2 == terminateMsg))
  186.             {
  187.                 GXExitPrinting();
  188.                 GXExitGraphics();
  189.             }
  190.         }
  191.     }
  192.         
  193.     return(anErr);
  194.     
  195. } // Device
  196.  
  197.  
  198.  
  199. // ------------------------------------------------------------------------
  200. // ENTRY POINT FOR LDEF
  201. // ------------------------------------------------------------------------
  202.  
  203. pascal void LDEF(
  204.     short         message,        // What operation to perform on list
  205.     Boolean     select,            // Is this cell to be selected or not?
  206.     Rect        *theRect,        // Rectangle of this cell, clipped to window
  207.     Cell        theCell,        // Which cell this is
  208.     short        dataOffset,        // Offset into data for this cell
  209.     short        dataLen,        // Length of data for this cell
  210.     ListHandle    theList)        // The list to act upon
  211. /*
  212.     An LDEF that works in two modes:
  213.         - if the first two characters of the cell are valid AppleTalk NBP names (ie, not ≈ ≈)
  214.           then the LDEF is just a basic text LDEF
  215.         - otherwise, it assumes the data is part of a PortListRec, which is
  216.           a structure for icons with text underneath
  217. */
  218.  
  219. {
  220. #pragma unused (theCell, dataLen)
  221.  
  222.     gxPortListRec        theCellContents;
  223.     Rect                iconRect;
  224.     unsigned char        hiliteMode;
  225.     
  226.     switch (message)
  227.         {
  228.         case lDrawMsg:
  229.         case lHiliteMsg:
  230.         
  231.             // save the data to avoid locking things down
  232.             if (dataLen > sizeof(theCellContents) )
  233.                 dataLen = sizeof(theCellContents);
  234.             BlockMove(((*(**theList).cells) + dataOffset), &theCellContents, dataLen );
  235.             
  236.             // draw the cell as an icon, but only if we see our magic marker at the front
  237.             if ( (theCellContents.firstMarker == '≈') && (theCellContents.secondMarker == '≈') )
  238.                 {
  239.                 // center the icon rect on the list with a top margin of 10 pixels
  240.                 iconRect.top = theRect->top + 10;
  241.                 iconRect.left = theRect->left + ((theRect->right - theRect->left) >> 1) - 16;
  242.                 iconRect.bottom = iconRect.top + 32;
  243.                 iconRect.right = iconRect.left + 32;
  244.                 
  245.                 
  246.                 // draw the icon
  247.                 if (theCellContents.iconSuiteHandle != nil)
  248.                     PlotIconSuite(&iconRect,
  249.                             ttNone, (select) ? ttSelected: ttNone,
  250.                             theCellContents.iconSuiteHandle);
  251.                             
  252.                 // Get the general area under the icon in which to draw the label
  253.                 iconRect.left = theRect->left + 2;
  254.                 iconRect.right = iconRect.left + (**theList).cellSize.h - 2;
  255.                 iconRect.top = iconRect.bottom + 2;
  256.                 iconRect.bottom = theRect->bottom;
  257.     
  258.                 // use a nice small font for the label            
  259.                 TextFont(applFont);
  260.                 TextSize(9);
  261.                 
  262.                     {
  263.                     short        labelWidth;
  264.                     short        rectWidth;
  265.                     short        labelHeight;
  266.                     FontInfo    theInfo;
  267.                 
  268.                     // Get rid of any text that was there before
  269.                     EraseRect(&iconRect);
  270.                     iconRect.top += 2;
  271.                     
  272.                     // compute the height of the label                    
  273.                     GetFontInfo(&theInfo);
  274.                     labelHeight = theInfo.ascent + theInfo.leading;
  275.                     
  276.                     // compute where to draw the text
  277.                     iconRect.bottom = iconRect.top + labelHeight;
  278.                     rectWidth = iconRect.right-iconRect.left;
  279.                     
  280.                     // truncate the string to fit within the box
  281.                     TruncString(rectWidth, theCellContents.iconName, smTruncEnd);
  282.                     
  283.                     // compute the new width of the string
  284.                     labelWidth = StringWidth(theCellContents.iconName);
  285.                     
  286.                     // center the string, draw it
  287.                     iconRect.left += (rectWidth >> 1) - (labelWidth >> 1);
  288.                     MoveTo(iconRect.left, iconRect.bottom);
  289.                     DrawString(theCellContents.iconName);
  290.                     
  291.                     if (select)
  292.                         {
  293.                         // compute right and lower edge of box bounding the text we just drew
  294.                         iconRect.right = iconRect.left + labelWidth;
  295.                         iconRect.bottom += theInfo.descent;
  296.                         
  297.                         // outset it, and invert it to select it
  298.                         InsetRect(&iconRect, -1, -1);
  299.                         hiliteMode = LMGetHiliteMode();
  300.                         BitClr(&hiliteMode, pHiliteBit);
  301.                         LMSetHiliteMode(hiliteMode);
  302.                         InvertRect(&iconRect);
  303.                         }
  304.                     }
  305.                     
  306.                 TextFont(applFont);
  307.                 TextSize(0);
  308.                 }
  309.             else
  310.                 {
  311.                 // how boring!  It's only text
  312.                 FontInfo    theInfo;
  313.                 Rect        ourRect;
  314.                 short        cellWidth;
  315.                 
  316.                 // add a margin to the rectangle
  317.                 ourRect = *theRect;
  318.                 ourRect.left += 4;
  319.                 --ourRect.right;
  320.                 cellWidth = ourRect.right - ourRect.left;
  321.                 
  322.                 // erase the rectangle
  323.                 GetFontInfo(&theInfo);
  324.                 EraseRect(theRect);
  325.                 MoveTo(ourRect.left, ourRect.bottom - theInfo.descent);
  326.                 
  327.                 // hey, you can't park that string here -- it's too big!
  328.                 if (TextWidth((Ptr) &theCellContents, 0, dataLen) > cellWidth )
  329.                     {
  330.                     // condense the text first
  331.                     TextFace(condense);
  332.                     
  333.                     // then truncate afterwards
  334.                     TruncText(cellWidth, (Ptr) &theCellContents, &dataLen, smTruncEnd);
  335.                     }
  336.                     
  337.                 // those darn other languages!
  338.                 if (GetSysJust() == teJustRight)
  339.                     Move(cellWidth-TextWidth((Ptr) &theCellContents, 0, dataLen) , 0);
  340.                     
  341.                 OldDrawText((Ptr) &theCellContents, 0, dataLen);
  342.                 
  343.                 // if selected, invert it
  344.                 if (select)
  345.                     {
  346.                     hiliteMode = LMGetHiliteMode();
  347.                     BitClr(&hiliteMode, pHiliteBit);
  348.                     LMSetHiliteMode(hiliteMode);
  349.                     InvertRect(theRect);
  350.                     }
  351.                     
  352.                 // normal text again
  353.                 TextFace(normal);
  354.                 }
  355.                 
  356.             break;
  357.             
  358.         } // switch
  359.         
  360. } // LDEF
  361.